// MathFuncsDll.cpp : Defines the exported functions for the DLL application.
//

#include "stdafx.h"
#include "StartMenuDll.h"
#include <stdexcept>
#include <iostream>
#include <CommCtrl.h>
#include <VersionHelpers.h>
#include <Ole2.h>
#include <atltypes.h>
#include <shellapi.h>
#include <map>
#include <Uxtheme.h>
#include "StartButton.h"
#include <time.h>
#include <sys/utime.h>
#include <Shlwapi.h>
#include "logging.h"
#include "StringUtils.h"
#include "WinVersion.h"

using namespace std;

HHOOK hookKeyboard = NULL;
HHOOK hookMouse = NULL;
static HHOOK hookMessages = NULL;

const int FIRST_BUTTON_BITMAP = 6801;

HWND g_TaskBar;
HWND g_WinStartButton, g_StartButtonOld;
//HWND g_ProgWin;
HWND g_Tooltip;

bool g_bVisibleStartMenu = false;
const int MAIN_TASK_BAR = 0;
std::map<int, TaskbarInfo> g_TaskbarInfos;
std::map<int, HWND> g_EdgeUIWndClasses;
static int g_LastTaskbar = MAIN_TASK_BAR;
static int g_NextTaskbar = 0;
static UINT g_StartMenuMsg;
bool g_bExitApp;
HWND g_HookWindowHandle;
RECT g_rectStartButton;
RECT g_oldRectRebar;
RECT g_ImmersiveSwitchLister;
HINSTANCE g_Instance;
bool g_bReplaceButton;
bool g_bReplaceAllTasksbars;
UINT g_TaskbarPosition = ABE_BOTTOM;
int g_TaskbarSize = 0;
int g_BMO, g_BKO, g_SBMO, g_SBKO, g_MBMO, g_TMBMO, g_DMS, g_DHE, g_RAFG, g_CMO, g_CLSO;

static DWORD g_StartButtonOldSizes[12];


int GetTaskbars() {
	int iTaskBarCounter = 0;
	for (std::map<int, TaskbarInfo>::const_iterator it = g_TaskbarInfos.begin(); it != g_TaskbarInfos.end(); ++it)
		iTaskBarCounter++;

	return iTaskBarCounter;
}
static const TaskbarInfo *GetDefaultTaskbarInfo(void)
{
	HMONITOR monitor = MonitorFromPoint(CPoint(GetMessagePos()), MONITOR_DEFAULTTONEAREST);
	for (std::map<int, TaskbarInfo>::const_iterator it = g_TaskbarInfos.begin(); it != g_TaskbarInfos.end(); ++it)
	{
		MONITORINFO info;
		HMONITOR monitor2 = NULL;
		if (it->second.startButton && GetTaskbarPosition(it->second.taskBar, &info, &monitor2, NULL) != 0xFFFFFFFF && monitor2 == monitor)
			return &it->second;
	}
	std::map<int, TaskbarInfo>::const_iterator it = g_TaskbarInfos.find(g_LastTaskbar);
	if (it != g_TaskbarInfos.end())
		return &it->second;
	return &g_TaskbarInfos.begin()->second;
}

TaskbarInfo *GetTaskbarInfo(int taskbarId)
{
	std::map<int, TaskbarInfo>::iterator it = g_TaskbarInfos.find(taskbarId);
	return (it == g_TaskbarInfos.end()) ? NULL : &it->second;
}

static void HandleSecondaryTaskbar(HWND hwnd){
	//if we access  to an map item and this does not exist, c++ will it create automatically
	int taskbarId = g_NextTaskbar++;
	TaskbarInfo &TaskbarInfo = g_TaskbarInfos[taskbarId];
	TaskbarInfo.taskBar = hwnd;
	TaskbarInfo.taskbarId = taskbarId;

	RTL_OSVERSIONINFOEXW tmpOSVersion = { 0 };
	tmpOSVersion.dwOSVersionInfoSize = sizeof(tmpOSVersion);

	GetOsVersion(&tmpOSVersion);

	if (TaskbarInfo.taskBar) {
		TaskbarInfo.rebar = FindWindowExW(hwnd, NULL, L"WorkerW", NULL);


		if (!IsWindows8OrGreater())
		{
			//StartButton has Classname "button"
			TaskbarInfo.oldButton = FindWindowExW(TaskbarInfo.taskBar, NULL, L"button", NULL);

		}
		else if (tmpOSVersion.dwMajorVersion > 8)
		{
			//StartButton has Classname "Start"
			TaskbarInfo.oldButton = FindWindowExW(TaskbarInfo.taskBar, NULL, L"Start", NULL);
		}
		if (g_bReplaceButton && g_bReplaceAllTasksbars){
			ShowWindow(TaskbarInfo.oldButton, SW_HIDE);

			InvalidateRect(TaskbarInfo.taskBar, NULL, TRUE);
			RecreateStartButton(taskbarId);
		}
		else {
			TaskbarInfo.startButton = TaskbarInfo.oldButton;
		}

		GetWindowRect(TaskbarInfo.taskBar, &TaskbarInfo.TaskBarPosition);

	}
}

static TaskbarInfo *FindTaskBarInfoButton(HWND button)
{
	for (std::map<int, TaskbarInfo>::iterator it = g_TaskbarInfos.begin(); it != g_TaskbarInfos.end(); ++it)
		if (it->second.startButton == button)
			return &it->second;	
	return NULL;
}

static TaskbarInfo *FindTaskBarInfoBar(HWND bar)
{
	for (std::map<int, TaskbarInfo>::iterator it = g_TaskbarInfos.begin(); it != g_TaskbarInfos.end(); ++it)
		if (it->second.taskBar == bar)
			return &it->second;
	return NULL;
}

HWND GetTaskbarStartButtonFromHandle(HWND handle) {
	TaskbarInfo *currentTaskbar = FindTaskBarInfoBar(handle);
	if (currentTaskbar)
		return currentTaskbar->startButton;
	else
		return NULL;
}

RECT GetStartButtonStartPosition(HWND Button) {
	TaskbarInfo *currentTaskbar = FindTaskBarInfoButton(Button);

	return GetTaskbarStartButtonRect(currentTaskbar->taskBar);
}

RECT GetStartButtonRectFromIndex(int TaskBarID) {
	HWND tmpTaskbar = NULL;
	for (std::map<int, TaskbarInfo>::iterator it = g_TaskbarInfos.begin(); it != g_TaskbarInfos.end(); ++it) {
		if (it->second.taskbarId == TaskBarID)
			tmpTaskbar = it->second.taskBar;
	}	

	return GetTaskbarStartButtonRect(tmpTaskbar);
}

HWND GetTaskbarHandleFromButton(HWND button) {
	TaskbarInfo *currentTaskbar = FindTaskBarInfoButton(button);
	if (currentTaskbar)
		return currentTaskbar->taskBar;
	else
		return 0;
}

UINT GetStartButtonPosition(HWND button) {
	TaskbarInfo *currentTaskbar = FindTaskBarInfoButton(button);
	MONITORINFO info;
	return GetTaskbarPosition(currentTaskbar->taskBar, &info, NULL, NULL);
}

UINT GetStartButtonPositionFromIndex(int TaskBarID) {
	TaskbarInfo *currentTaskbar = NULL;

	for (std::map<int, TaskbarInfo>::iterator it = g_TaskbarInfos.begin(); it != g_TaskbarInfos.end(); ++it) {
		if (it->second.taskbarId == TaskBarID)
			currentTaskbar = &it->second;
	}

	MONITORINFO info;
	if (currentTaskbar != NULL) {
		return GetTaskbarPosition(currentTaskbar->taskBar, &info, NULL, NULL);
	}
	else return 0;
}

UINT GetStartButtonTPosition(HWND taskbar) {
	MONITORINFO info;
	return GetTaskbarPosition(taskbar, &info, NULL, NULL);
}

bool IsTaskbarStartButton(HWND handle) {
	TaskbarInfo *currentTaskbar = FindTaskBarInfoButton(handle);
	return (currentTaskbar != NULL);
}

RECT GetTaskbarStartButtonRect(HWND handle){
	TaskbarInfo *currentTaskbar = FindTaskBarInfoBar(handle);
	if (currentTaskbar)
		return currentTaskbar->Position;
	else
		return RECT();
}


static BOOL CALLBACK FindTaskBarEnum(HWND hwnd, LPARAM lParam)
{
	// look for top-level window with class "Shell_TrayWnd" and process ID=lParam
	DWORD process;
	GetWindowThreadProcessId(hwnd, &process);
	if (process != lParam) return TRUE;
	wchar_t name[1000];
	GetClassNameW(hwnd, name, _countof(name));

	if (_wcsicmp(name, L"Shell_TrayWnd") != 0) return TRUE;
	g_TaskBar = hwnd;
	return FALSE;
}


static BOOL CALLBACK HookAllTaskbarsEnum(HWND hwnd, LPARAM lParam)
{
	// look for top-level windows with class "Shell_SecondaryTrayWnd" in the current thread
	//if (GetWindowThreadProcessId(hwnd, NULL) != GetCurrentThreadId()) return TRUE;
	wchar_t name[1000];
	GetClassNameW(hwnd, name, _countof(name));
	if (_wcsicmp(name, L"Shell_SecondaryTrayWnd") == 0)
		HandleSecondaryTaskbar(hwnd);
	return TRUE;
}

static BOOL CALLBACK FindStartButtonEnum(HWND hwnd, LPARAM lParam)
{
	// look for top-level window in the current thread with class "button"
	wchar_t name[256];
	GetClassNameW(hwnd, name, _countof(name));
	
	if (_wcsicmp(name, L"button") != 0) 
		return TRUE;

	g_WinStartButton = hwnd;
	return FALSE;
}

bool FindTaskBar(DWORD process)
{
	// find the taskbar
	EnumWindows(FindTaskBarEnum, process);
	LogMessage("Taskbar Handle: ", g_TaskBar, LOG_DEBUG);
	if (g_TaskBar)
	{

		// find start button
		if (!IsWindows8OrGreater())
		{
			//We have a Windows version befor Windows 8.0 he is the StartButton Class Named "Button"
			EnumThreadWindows(GetWindowThreadProcessId(g_TaskBar, NULL), FindStartButtonEnum, NULL);
			LogMessage("StartButton Handle: ", g_WinStartButton, LOG_DEBUG);
			
		}
		else if (IsWindows8Point1OrGreater())
		{
			//we have a Windows in Version 8.1 or greater and the StartButton Class is named "Start"
			g_WinStartButton = FindWindowExW(g_TaskBar, NULL, L"Start", NULL);
			LogMessage("StartButton Handle: ", g_WinStartButton, LOG_DEBUG);
		}

	}
	//if we had a hwnd to Taskbar return true otherwise false
	return g_TaskBar != NULL;
}

static void FindTaskBar(void)
{
	if (!g_TaskBar)
	{
		g_StartMenuMsg = RegisterWindowMessageW(L"WinKStart.StartMenuMsg");
		FindTaskBar(GetCurrentProcessId());

		if (!g_TaskBar) g_TaskBar = (HWND)1;
	}
}

void SetDefaultButtonState(){
	for (std::map<int, TaskbarInfo>::iterator it = g_TaskbarInfos.begin(); it != g_TaskbarInfos.end(); ++it){
		const TaskbarInfo *taskBar = &it->second;
		PostMessage(taskBar->startButton, WM_LBUTTONUP, NULL, 'CLSM');
	}
}


UINT GetTaskbarPosition(HWND taskBar, MONITORINFO *pInfo, HMONITOR *pMonitor, RECT *pRc)
{
	if (!IsWindow(taskBar))
		return 0xFFFFFFFF;
	if (taskBar == g_TaskBar)
	{
		APPBARDATA appbar = { sizeof(appbar), taskBar };
		SHAppBarMessage(ABM_GETTASKBARPOS, &appbar);
		if (pRc) *pRc = appbar.rc;
		if (pInfo)
		{
			pInfo->cbSize = sizeof(MONITORINFO);
			HMONITOR monitor = MonitorFromRect(&appbar.rc, MONITOR_DEFAULTTONEAREST);
			GetMonitorInfo(monitor, pInfo);
			if (pMonitor) *pMonitor = monitor;
		}
		return appbar.uEdge;
	}
	RECT rc;
	if (GetWindowRgnBox(taskBar, &rc) != ERROR)
		MapWindowPoints(taskBar, NULL, (POINT*)&rc, 2);
	else
		GetWindowRect(taskBar, &rc);
	MONITORINFO info = { sizeof(info) };
	HMONITOR monitor = MonitorFromRect(&rc, MONITOR_DEFAULTTONEAREST);
	GetMonitorInfo(monitor, &info);
	if (pMonitor) *pMonitor = monitor;
	int dx = rc.left + rc.right - info.rcWork.left - info.rcWork.right;
	int dy = rc.top + rc.bottom - info.rcWork.top - info.rcWork.bottom;
	if (pRc) *pRc = rc;
	if (pInfo) *pInfo = info;
	if (dx<-abs(dy)) return ABE_LEFT;
	if (dx>abs(dy)) return ABE_RIGHT;
	if (dy<-abs(dx)) return ABE_TOP;
	return ABE_BOTTOM;
}

//Check startbutton rect to contain the given Point 
bool PointIsInStartButton(POINT Pos)
{
	const TaskbarInfo *taskBar = GetTaskbarInfo(0);

	RECT rc2;
	GetWindowRect(taskBar->startButton, &rc2);
	return (bool)PtInRect(&rc2, Pos);
}

// Returns true if the mouse is on the taskbar portion of the start button
bool PointAroundStartButton(int taskbarId)
{
	const TaskbarInfo *taskBar = GetTaskbarInfo(taskbarId);
	if (!taskBar) return false;
	CPoint pt(GetMessagePos());
	RECT rc;
	GetWindowRect(taskBar->taskBar, &rc);
	if (!PtInRect(&rc, pt))
		return false;

	UINT uEdge = GetTaskbarPosition(taskBar->taskBar, NULL, NULL, NULL);
	if (g_bReplaceButton)
	{
		// if there is a custom start button, it determines the width of the area
		RECT rc2;
		GetWindowRect(taskBar->startButton, &rc2);
		if (uEdge == ABE_LEFT || uEdge == ABE_RIGHT)
		{
			rc2.left = rc.left;
			rc2.right = rc.right;
		}
		else
		{
			rc2.top = rc.top;
			rc2.bottom = rc.bottom;
		}
		return PtInRect(&rc2, pt) != 0;
	}
	else
	{
		// the Vista/Win7 start button

		// in Classic mode there are few pixels at the edge of the taskbar that are not covered by a child window
		// we nudge the point to be in the middle of the taskbar to avoid those pixels
		// also ignore clicks on the half of the taskbar that doesn't contain the start button
		if (uEdge == ABE_LEFT || uEdge == ABE_RIGHT)
		{
			pt.x = (rc.left + rc.right) / 2; // vertical taskbar, set X
			if (pt.y>(rc.top + rc.bottom) / 2)
				return false;
		}
		else
		{
			pt.y = (rc.top + rc.bottom) / 2; // vertical taskbar, set Y
			if (pt.x>(rc.left + rc.right) / 2)
			{
				if (!(GetWindowLong(taskBar->taskBar, GWL_EXSTYLE)&WS_EX_LAYOUTRTL))
					return false;
			}
			else
			{
				if (GetWindowLong(taskBar->taskBar, GWL_EXSTYLE)&WS_EX_LAYOUTRTL)
					return false;
			}
		}
		ScreenToClient(taskBar->taskBar, &pt);
		HWND child = ChildWindowFromPointEx(taskBar->taskBar, pt, CWP_SKIPINVISIBLE | CWP_SKIPTRANSPARENT);
		if (child != NULL && child != taskBar->taskBar)
		{
			// ignore the click if it is on a child window (like the rebar or the tray area)
			return false;
		}
		return true;
	}
}

void RecreateStartButton(int taskbarId)
{
	if (!g_bReplaceButton) return;
	for (std::map<int, TaskbarInfo>::iterator it = g_TaskbarInfos.begin(); it != g_TaskbarInfos.end(); ++it)
	{
		TaskbarInfo *taskBar = &it->second;
		if (taskbarId >= 0 && taskBar->taskbarId != taskbarId)
			continue;
		if (!taskBar->rebar)
			continue;
		//RevokeDragDrop(taskBar->startButton);
		LogMessage("Destroy old StartButton ", LOG_DEBUG);
		DestroyStartButton(taskBar->taskbarId);
		RECT rcTask;
		GetWindowRect(taskBar->taskBar, &rcTask);
		RECT rcTask2 = rcTask;
		MONITORINFO info;
		UINT uEdge = GetTaskbarPosition(taskBar->taskBar, &info, NULL, NULL);
		//Set the Left/Top Position for the startbutton
		if (uEdge == ABE_TOP || uEdge == ABE_BOTTOM)
		{
			if (rcTask2.left<info.rcMonitor.left) rcTask2.left = info.rcMonitor.left;
			if (rcTask2.right>info.rcMonitor.right) rcTask2.right = info.rcMonitor.right;
		}
		else
		{
			if (rcTask2.top<info.rcMonitor.top) rcTask2.top = info.rcMonitor.top;
			//rcTask2.left = 0;

		}		

		if (!IsTaskbarSmallIcons())
		{
			bool bClassic;
			if (IsWindows8OrGreater() == false)
				bClassic = !IsAppThemed();
			else
			{
				HIGHCONTRAST contrast = { sizeof(contrast) };
				bClassic = (SystemParametersInfo(SPI_GETHIGHCONTRAST, sizeof(contrast), &contrast, 0) && (contrast.dwFlags&HCF_HIGHCONTRASTON));
			}
			if (!bClassic)
			{
				if (uEdge == ABE_TOP)
					OffsetRect(&rcTask2, 0, -1);
				else if (uEdge == ABE_BOTTOM)
					OffsetRect(&rcTask2, 0, 1);
			}
		}
		LogMessage("Create new StartButton ", LOG_DEBUG);
		//rcTask2.left = 0;
		taskBar->startButton = CreateStartButton(taskBar->taskbarId, taskBar->taskBar, taskBar->rebar, rcTask2);
		GetWindowRect(taskBar->startButton, &taskBar->Position);

		RTL_OSVERSIONINFOEXW tmpOSVersion = { 0 };
		tmpOSVersion.dwOSVersionInfoSize = sizeof(tmpOSVersion);

		GetOsVersion(&tmpOSVersion);

		if (!taskBar->startButton)
		{
			HWND StartButtonHandle;
			//windows inline startbutton hidden
			if (!IsWindows8OrGreater())
			{
				//StartButton has Classname "button"
				StartButtonHandle = FindWindowExW(taskBar->taskBar, NULL, L"button", NULL);
				if (StartButtonHandle)
					ShowWindow(StartButtonHandle, SW_HIDE);
			}
			else if (tmpOSVersion.dwMajorVersion > 8) //IsWindows8Point1OrGreater())
			{
				//StartButton has Classname "Start"
				StartButtonHandle = FindWindowExW(taskBar->taskBar, NULL, L"Start", NULL);
				if (StartButtonHandle)
					ShowWindow(StartButtonHandle, SW_HIDE);
			}			
		}

		taskBar->rebarOffset = GetStartButtonSize(taskBar->taskbarId);

		PostMessage(taskBar->taskBar, WM_SIZE, SIZE_RESTORED, MAKELONG(rcTask.right - rcTask.left, rcTask.bottom - rcTask.top));
	}	
}

void CheckTaskbarSizeChanged(UINT Position)
{
	RECT tmpCurrentTaskbarRect;
	UINT tmpTaskBarPosition = 3;
	POINT ptNewPosition;
	wchar_t debugstring[1030];
	int iTaskbarSize = 0;
	int iButtonSize = 0;

	for (std::map<int, TaskbarInfo>::iterator it = g_TaskbarInfos.begin(); it != g_TaskbarInfos.end(); ++it)
	{
		GetWindowRect(it->second.taskBar, &tmpCurrentTaskbarRect);
		if (g_TaskbarPosition == ABE_LEFT || g_TaskbarPosition == ABE_RIGHT) {
			if (tmpCurrentTaskbarRect.right - tmpCurrentTaskbarRect.left != it->second.TaskBarPosition.right - it->second.TaskBarPosition.left){
				ptNewPosition.y = 0;
				
				iTaskbarSize = tmpCurrentTaskbarRect.right - tmpCurrentTaskbarRect.left;
				iButtonSize = it->second.Position.right - it->second.Position.left;
				ptNewPosition.x = (iTaskbarSize - iButtonSize) / 2;
				
				SetWindowPos(it->second.startButton, HWND_TOP, ptNewPosition.x, ptNewPosition.y, 56, 56, SWP_NOSIZE);
				it->second.TaskBarPosition = tmpCurrentTaskbarRect;
			}
		}
		else {		
				ptNewPosition.x = 0;
				ptNewPosition.y = 0; 

				SetWindowPos(it->second.startButton, HWND_TOPMOST, ptNewPosition.x, ptNewPosition.y, 0, 0, SWP_NOSIZE);

				it->second.TaskBarPosition = tmpCurrentTaskbarRect;			
		}
	}
}

void CheckTaskbarMoved(){
	UINT tmpTaskbarPos = GetTaskbarPosition(g_TaskBar, NULL, NULL, NULL);
	if (g_TaskbarPosition != tmpTaskbarPos) {
		g_TaskbarPosition = tmpTaskbarPos;
		g_TaskbarInfos.clear();
		g_NextTaskbar = 0;

		CloseStartMenu();
		InitStartButton();
	}
	else {
		CheckTaskbarSizeChanged(tmpTaskbarPos);
	}
}

void InitStartButton()
{
	//get the DPI settings
	HDC ohdc = GetDC(NULL);
	g_DPI = GetDeviceCaps(ohdc, LOGPIXELSY);
	ReleaseDC(NULL, ohdc);

	//get Window Handle for Progman
	g_ProgWin = FindWindowExW(NULL, NULL, L"Progman", NULL);
	DWORD process;
	DWORD thread = GetWindowThreadProcessId(g_ProgWin, &process);
	FindTaskBar(process);

	//if we access  to an map item and this does not exist, c++ will it create automatically
	int taskbarId = g_NextTaskbar++;
	TaskbarInfo &TaskbarInfo = g_TaskbarInfos[taskbarId];
	TaskbarInfo.taskBar = g_TaskBar;
	TaskbarInfo.taskbarId = taskbarId;

	RTL_OSVERSIONINFOEXW tmpOSVersion = { 0 };
	tmpOSVersion.dwOSVersionInfoSize = sizeof(tmpOSVersion);

	GetOsVersion(&tmpOSVersion);

	if (g_bReplaceButton)
	{
		g_StartButtonOld = g_WinStartButton;

		LogMessage("Replace StartButton ", LOG_ACTIONS);
		TaskbarInfo.rebar = FindWindowEx(g_TaskBar, NULL, REBARCLASSNAME, NULL);
		if (TaskbarInfo.rebar)
		{
			
			if (g_StartButtonOld)
			{
				ShowWindow(g_StartButtonOld, SW_HIDE);
				if (IsWindows8OrGreater() == false)
				{
					// Windows 7 draws the start button on the taskbar as well
					// so we zero out the bitmap resources
					HMODULE hExplorer = GetModuleHandle(NULL);
					for (int res = 0; res < _countof(g_StartButtonOldSizes); res++)
					{
						HRSRC hrSrc = FindResource(hExplorer, MAKEINTRESOURCE(res + FIRST_BUTTON_BITMAP), RT_BITMAP);
						if (hrSrc)
						{
							HGLOBAL hRes = LoadResource(hExplorer, hrSrc);
							if (hRes)
							{
								void *pRes = LockResource(hRes);
								if (pRes)
								{
									DWORD old;
									BITMAPINFOHEADER *pHeader = (BITMAPINFOHEADER*)pRes;
									if (pHeader->biWidth)
									{
										g_StartButtonOldSizes[res] = MAKELONG(pHeader->biWidth, pHeader->biHeight);
										VirtualProtect(pRes, sizeof(BITMAPINFOHEADER), PAGE_READWRITE, &old);
										pHeader->biHeight = pHeader->biWidth = 0;
										VirtualProtect(pRes, sizeof(BITMAPINFOHEADER), old, &old);
									}
								}
							}
						}
					}
				}
				SendMessage(TaskbarInfo.taskBar, WM_SETTINGCHANGE, 0, 0);
			}

		}



		if (tmpOSVersion.dwMajorVersion > 8) //  IsWindows8Point1OrGreater() == true)
		{
			TaskbarInfo.oldButton = FindWindowExW(TaskbarInfo.taskBar, NULL, L"Start", NULL);
			g_StartButtonOld = TaskbarInfo.oldButton;
			ShowWindow(TaskbarInfo.oldButton, SW_HIDE);
		}

		InvalidateRect(TaskbarInfo.taskBar, NULL, TRUE);
		LogMessage("Create the new StartButton ", LOG_ACTIONS);
		RecreateStartButton(taskbarId);
		g_WinStartButton = TaskbarInfo.startButton;
		GetWindowRect(TaskbarInfo.taskBar, &TaskbarInfo.TaskBarPosition);
	}
	else {
		TaskbarInfo.startButton = g_WinStartButton;
		GetWindowRect(TaskbarInfo.startButton, &TaskbarInfo.Position);
		GetWindowRect(TaskbarInfo.taskBar, &TaskbarInfo.TaskBarPosition);

		InvalidateRect(TaskbarInfo.taskBar, NULL, TRUE);
		LogMessage("Use Windows StartButton ", LOG_ACTIONS);
		TaskbarInfo.startButton = g_WinStartButton;
	}

	//Get Initial Task-bar position
	g_TaskbarPosition = GetTaskbarPosition(TaskbarInfo.taskBar, NULL, NULL, NULL);

	if (IsWindows8OrGreater() == true)
	{
		if (!IsWindows8Point1OrGreater())
		{
			GetWindowRect(TaskbarInfo.rebar, &g_oldRectRebar);
			RECT newRebarRect = g_oldRectRebar;
			newRebarRect.top = 0;
			newRebarRect.left = 55;
			SetWindowPos(TaskbarInfo.rebar, HWND_TOP, newRebarRect.left, newRebarRect.top, newRebarRect.right - 54, newRebarRect.bottom, SWP_SHOWWINDOW);
		}

	}

	EnumWindows(HookAllTaskbarsEnum, 0);

}

void CloseStartMenu()
{
	for (std::map<int, TaskbarInfo>::iterator it = g_TaskbarInfos.begin(); it != g_TaskbarInfos.end(); ++it){
		const TaskbarInfo *taskBar = &it->second;

		if (g_bReplaceButton)
		{
			LogMessage("Destroy new StartButton ", LOG_ACTIONS);
			DestroyStartButton(taskBar->taskbarId);

			SendMessage(taskBar->taskBar, WM_SETTINGCHANGE, 0, 0);
			if (g_StartButtonOld)
			{
				LogMessage("Restore old StartButton ", LOG_ACTIONS);
				SendMessage(taskBar->oldButton, WM_THEMECHANGED, 0, 0);
				ShowWindow(taskBar->oldButton, SW_SHOW);
			}
		}
	}
	LogMessage("Unload WinKStart Button done ", LOG_ACTIONS);
}
